home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Medal Software 2
/
Gold Medal Software Volume 2 (Gold Medal) (1994).iso
/
windows
/
comms
/
recomm10.arj
/
LNKLIST.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-11
|
23KB
|
564 lines
/****************************************************************************
* Program Name... LnkList.OBJ
* Filename....... LnkList.C
* Author......... John A. Kuhn
* Version........ 1.0
* Version Date... June 8, 1992
* Comments....... Generic linked list routines - this module uses
* the caller's data segment -GW
*
* $Header$
* $Modtime$
* $Log$
*
***************************************************************************/
#include <windows.h>
#include "wnetbios.h"
/* internal function prototypes */
static HANDLE CreateListItemNode(HANDLE hItemData,
HANDLE hPrevItem,
HANDLE hNextItem);
static HANDLE GetListItemNode(HANDLE hListHead, WORD wItemIndex);
static WORD GetListItemIndex(HANDLE hListHead, HANDLE hListItem);
/*====================================================================*/
/* */
/* Internal Functions */
/* */
/*====================================================================*/
/*--------------------------------------------------------------------*/
/* CreateListItem */
/* */
/* This function creates a unlinked list item node by alloc'ing */
/* memory for a node and assigns the specified item data handle */
/* next item handle to it. */
/* */
/* Arguments: */
/* */
/* hItemData = Handle to item data */
/* hPrevItem = Handle to previous item node */
/* hNextItem = Handle to next item node */
/* */
/* Globals: None */
/* */
/* Return: Returns a handle to the list item node or NULL */
/* if it failed to create node. */
/* */
/*--------------------------------------------------------------------*/
static HANDLE CreateListItemNode(HANDLE hItemData,
HANDLE hPrevItem,
HANDLE hNextItem)
{
HANDLE hListItem;
NPLISTITEM npListItem;
hListItem = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_SHARE, sizeof(LISTITEM));
if (hListItem != NULL)
{
npListItem = (NPLISTITEM) GlobalLock(hListItem);
npListItem->hItemData = hItemData;
npListItem->hPrevItem = hPrevItem;
npListItem->hNextItem = hNextItem;
GlobalUnlock(hListItem);
}
return(hListItem);
}
/*--------------------------------------------------------------------*/
/* GetListItemNode */
/* */
/* This function traverses through the specified linked list */
/* and returns the handle to the specified items node. */
/* */
/* Arguments: */
/* */
/* hListHead = Handle of the lists header node. */
/* wItemIndex = Index of List item node (based at 1) */
/* An index not in list returns NULL. */
/* */
/* Globals: None */
/* */
/* Return: Returns the handle of the specified list item */
/* node or NULL if item not in list. */
/* */
/*--------------------------------------------------------------------*/
HANDLE GetListItemNode(HANDLE hListHead, WORD wItemIndex)
{
NPLISTHEAD npList;
NPLISTITEM npNextItem;
HANDLE hNextItem;
WORD wNoListItems;
WORD wIndex = 0;
HANDLE hItem = NULL;
npList = (NPLISTHEAD) GlobalLock(hListHead);
if (npList == NULL)
return (NULL);
wNoListItems = npList->wCount;
hNextItem = npList->hFirstItem;
GlobalUnlock(hListHead);
if (wItemIndex == 0 || wItemIndex > wNoListItems)
return(NULL);
while (hNextItem != NULL && wIndex != wItemIndex)
{
hItem = hNextItem;
npNextItem = (NPLISTITEM) GlobalLock(hNextItem);
hNextItem = npNextItem->hNextItem;
GlobalUnlock(hNextItem);
++wIndex;
}
return(hItem);
}
/*--------------------------------------------------------------------*/
/* GetListItemIndex */
/* */
/* This function traverses through the specified linked list */
/* and returns the index of the list item node with the specified */
/* handle. */
/* */
/* Arguments: */
/* */
/* hListHead = Handle of the lists header node. */
/* hListItem = Handle of List item node. */
/* */
/* Globals: None */
/* */
/* Return: Returns the index of the specified list item node */
/* or 0 if item does not exist. */
/* */
/*--------------------------------------------------------------------*/
static WORD GetListItemIndex(HANDLE hListHead, HANDLE hListItem)
{
NPLISTHEAD npList;
NPLISTITEM npNextItem;
HANDLE hNextItem;
WORD wIndex = 0;
npList = (NPLISTHEAD) GlobalLock(hListHead);
hNextItem = npList->hFirstItem;
GlobalUnlock(hListHead);
while (hNextItem != hListItem && hNextItem != NULL)
{
npNextItem = (NPLISTITEM) GlobalLock(hNextItem);
hNextItem = npNextItem->hNextItem;
GlobalUnlock(hNextItem);
++wIndex;
}
if (hNextItem != NULL)
return (wIndex);
else
return (0);
}
/*====================================================================*/
/* */
/* A P I Functions */
/* */
/*====================================================================*/
/*--------------------------------------------------------------------*/
/* CreateLinkedList */
/* */
/* This function ... */
/* */
/* Arguments: None */
/* */
/* Globals: None */
/* */
/* Return: None */
/* */
/*--------------------------------------------------------------------*/
HANDLE FAR PASCAL CreateLinkedList(void)
{
HANDLE hListHead;
NPLISTHEAD npList;
hListHead = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_SHARE, sizeof(LISTHEAD));
if (hListHead != NULL)
{
npList = (NPLISTHEAD) GlobalLock(hListHead);
npList->wCount = 0;
npList->hLastItem = NULL;
npList->hFirstItem = NULL;
GlobalUnlock(hListHead);
}
return(hListHead);
}
/*--------------------------------------------------------------------*/
/* AddListItem */
/* */
/* This function adds a list item to the end of the specified */
/* list. */
/* */
/* Arguments: */
/* */
/* hListHead = Handle of the lists header node. */
/* hItemData = Handle of list item data */
/* */
/* Globals: None */
/* */
/* Return: Returns TRUE if successful else FALSE */
/* */
/*--------------------------------------------------------------------*/
BOOL FAR PASCAL AddListItem(HANDLE hListHead, HANDLE hItemData)
{
NPLISTHEAD npList;
NPLISTITEM npItem;
HANDLE hItem;
npList = (NPLISTHEAD) GlobalLock(hListHead);
if (npList == NULL)
return (FALSE);
if (npList->wCount == MAX_LIST_COUNT)
{
GlobalUnlock(hListHead);
return (FALSE);
}
hItem = CreateListItemNode(hItemData, npList->hLastItem, NULL);
if (hItem == NULL)
{
GlobalUnlock(hListHead);
return (FALSE);
}
if (npList->hFirstItem == NULL)
{
npList->hFirstItem = hItem;
}
else
{
npItem = (NPLISTITEM) GlobalLock(npList->hLastItem);
npItem->hNextItem = hItem;
GlobalUnlock(npList->hLastItem);
}
npList->hLastItem = hItem;
++npList->wCount;
GlobalUnlock(hListHead);
return (TRUE);
}
/*--------------------------------------------------------------------*/
/* DeleteListItem */
/* */
/* This function deletes the specified list item node */
/* from the specified list. */
/* */
/* Arguments: */
/* */
/* hListHead = Handle of the lists header node. */
/* wItemIndex = Index of a list item */
/* */
/* Globals: None */
/* */
/* Return: Returns TRUE if successfull else FALSE if failed */
/* because list item does not exist. */
/* */
/*--------------------------------------------------------------------*/
BOOL FAR PASCAL DeleteListItem(HANDLE hListHead, WORD wItemIndex)
{
HANDLE hItem;
NPLISTITEM npPrevItem, npNextItem, npItem;
NPLISTHEAD npList;
npList = (NPLISTHEAD) GlobalLock(hListHead);
if (npList == NULL)
return(FALSE);
if (wItemIndex == 0 || wItemIndex > npList->wCount)
{
GlobalUnlock(hListHead);
return(FALSE);
}
hItem = GetListItemNode(hListHead, wItemIndex);
if (hItem == NULL)
{
GlobalUnlock(hListHead);
return(FALSE);
}
npItem = (NPLISTITEM) GlobalLock(hItem);
if (npItem->hNextItem != NULL)
{
npNextItem = (NPLISTITEM) GlobalLock(npItem->hNextItem);
npNextItem->hPrevItem = npItem->hPrevItem;
GlobalUnlock(npItem->hNextItem);
}
if (npItem->hPrevItem != NULL)
{
npPrevItem = (NPLISTITEM) GlobalLock(npItem->hPrevItem);
npPrevItem->hNextItem = npItem->hNextItem;
GlobalUnlock(npItem->hPrevItem);
}
if (hItem == npList->hFirstItem)
npList->hFirstItem = npItem->hNextItem;
if (hItem == npList->hLastItem)
npList->hLastItem = npItem->hPrevItem;
// delete the items node
GlobalUnlock(hItem);
GlobalFree(hItem);
--npList->wCount;
GlobalUnlock(hListHead);
return (TRUE);
}
/*--------------------------------------------------------------------*/
/* InsertListItem */
/* */
/* This function inserts a list item before the specified item */
/* of the specified list. */
/* */
/* Arguments: */
/* */
/* hListHead = Handle of the lists header node. */
/* hItemData = Handle of list item data */
/* wItemIndex = Index of a list item */
/* */
/* */
/* Globals: None */
/* */
/* Return: Returns TRUE if successfull else FALSE */
/* */
/*--------------------------------------------------------------------*/
BOOL FAR PASCAL InsertListItem(HANDLE hListHead, HANDLE hItemData, WORD wItemIndex)
{
HANDLE hNewItem, hItem;
NPLISTITEM npItem, npPrevItem;
NPLISTHEAD npList;
npList = (NPLISTHEAD) GlobalLock(hListHead);
if (npList == NULL)
return (FALSE);
if (npList->wCount == MAX_LIST_COUNT)
{
GlobalUnlock(hListHead);
return (FALSE);
}
if (wItemIndex == 0 || wItemIndex >= npList->wCount)
{
GlobalUnlock(hListHead);
return(AddListItem(hListHead, hItemData));
}
hItem = GetListItemNode(hListHead, wItemIndex);
if (hItem == NULL)
{
GlobalUnlock(hListHead);
return(FALSE);
}
npItem = (NPLISTITEM) GlobalLock(hItem);
hNewItem = CreateListItemNode(hItemData, npItem->hPrevItem, hItem);
if (hNewItem == NULL)
{
GlobalUnlock(hItem);
GlobalUnlock(hListHead);
return(FALSE);
}
if (npItem->hPrevItem != NULL)
{
npPrevItem = (NPLISTITEM) GlobalLock(npItem->hPrevItem);
npPrevItem->hNextItem = hNewItem;
GlobalUnlock(npItem->hPrevItem);
}
if (hItem == npList->hFirstItem)
npList->hFirstItem = hNewItem;
npItem->hPrevItem = hNewItem;
++npList->wCount;
GlobalUnlock(hNewItem);
GlobalUnlock(hItem);
GlobalUnlock(hListHead);
return(TRUE);
}
/*--------------------------------------------------------------------*/
/* SortLinkedList */
/* */
/* This function ... */
/* */
/* Arguments: */
/* */
/* hListHead = Handle of the lists header node. */
/* */
/* Globals: None */
/* */
/* Return: None */
/* */
/*--------------------------------------------------------------------*/
BOOL FAR PASCAL SortLinkedList(HANDLE hListHead, WORD wFlags, FARPROC lpCompFunc)
{
return(TRUE);
}
/*--------------------------------------------------------------------*/
/* EnumListItems */
/* */
/* This function enumerates all list items in list order calling */
/* a user supplied enumeration callback function for each item */
/* in the list. */
/* */
/* Arguments: */
/* */
/* hListHead = Handle of the lists header node. */
/* lpEnumFunc = Pointer to an enumeration callback function */
/* with the following prototype... */
/* */
/* BOOL FAR PASCAL EnumFunc(WORD wIndex, HANDLE hItemData, LONG lParam) */
/* */
/* The enumeration function receives 3 args; the */
/* index of the item, and the handle to the items */
/* data. The enum function can return TRUE to */
/* continue the enumeration or FALSE to end it. */
/* */
/* Globals: None */
/* */
/* Return: Returns TRUE if all list items were enumerated or */
/* FALSE is enumeration was aborted early becuase */
/* users callback function returned FALSE */
/*--------------------------------------------------------------------*/
BOOL FAR PASCAL EnumListItems(HANDLE hListHead,
FARPROC lpEnumFunc,
ENUM_MODE mode,
LONG lParam)
{
NPLISTHEAD npList;
NPLISTITEM npItem;
HANDLE hItem;
HANDLE hCurItem;
HANDLE hItemData;
WORD wIndex = 0;
if (lpEnumFunc == NULL)
return (FALSE);
npList = (NPLISTHEAD) GlobalLock(hListHead);
if (npList == NULL)
return (FALSE);
hItem = (mode == ENUM_FORWARD) ? npList->hFirstItem : npList->hLastItem;
GlobalUnlock(hListHead);
while (hItem != NULL)
{
hCurItem = hItem;
npItem = (NPLISTITEM) GlobalLock(hItem);
hItem = (mode == ENUM_FORWARD) ? npItem->hNextItem : npItem->hPrevItem;
GlobalUnlock(hItem);
npItem = (NPLISTITEM) GlobalLock(hCurItem);
hItemData = npItem->hItemData;
GlobalUnlock(hCurItem);
if ((*lpEnumFunc)(++wIndex, hItemData, lParam) == FALSE)
return(FALSE);
}
return(TRUE);
}
/*--------------------------------------------------------------------*/
/* GetListCount */
/* */
/* This function ... */
/* */
/* Arguments: */
/* */
/* hListHead = Handle to list header node */
/* */
/* Globals: None */
/* */
/* Return: Returns number of items in the list. */
/* */
/*--------------------------------------------------------------------*/
WORD FAR PASCAL GetListCount(HANDLE hListHead)
{
NPLISTHEAD npList;
BOOL wNoListItems;
npList = (NPLISTHEAD) GlobalLock(hListHead);
if(npList != (NPLISTHEAD)NULL)
{
wNoListItems = npList->wCount;
}
GlobalUnlock(hListHead);
return(wNoListItems);
}
/*--------------------------------------------------------------------*/
/* DestroyLinkedList */
/* */
/* This function ... */
/* */
/* Arguments: */
/* */
/* hListHead = Handle to list head. */
/* */
/* Globals: None */
/* */
/* Return: Returns handle to item data or NULL if failed */
/* */
/*--------------------------------------------------------------------*/
void FAR PASCAL DestroyLinkedList(HANDLE hListHead)
{
WORD wNoListItems;
WORD wIndex;
wNoListItems = GetListCount(hListHead);
// delete all remaining list item nodes
for (wIndex = wNoListItems; wIndex > 0; --wIndex)
DeleteListItem(hListHead, wIndex);
// delete list header node
GlobalFree(hListHead);
}